package com.app.teaware.util;

import android.text.TextUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;

/**
 * 16进制数据转换工具
 * 
 * @author zch
 *
 */
public class HexUtil {


	public static boolean isValidHexString(String data) {
		String reg = "[0-9a-fA-F]*";
		if (!TextUtils.isEmpty(data))
			return data.matches(reg);
		return false;
	}


	
	/**
	 * 将16进制字符串转成二进制字节数据，目前此函数只支持长度不超过600个字符的16进制字符串的转换。
	 * @param //buf 16进制字符串(长度必须是2的倍数，因为两个16进制字符转换为一个二进制字节，分别代表一个字节的高四位和低四位):例(0x):0A02
	 * @return 二进制字节数组
	 */
	public static byte[] Str2Hex(String hexStr) 
	{
		if(TextUtils.isEmpty(hexStr))
			return null;
		
		try {
			String chex = "0123456789ABCDEF";
			int len = hexStr.length();
			byte[] hexbuf = new byte[len/2];
		    for (int i = 0; i < len; i += 2)
		    {
		      byte hnx = (byte)chex.indexOf(hexStr.toUpperCase().substring(i, i + 1));
		      byte lnx = 0;
		      if (hexStr.length() > i + 1) {
		        lnx = (byte)chex.indexOf(hexStr.toUpperCase().substring(i + 1, i + 2));
		      }
		      hexbuf[(i / 2)] = ((byte)(hnx << 4 & 0xFF | lnx & 0xFF));
		    }
			
			return hexbuf;
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}



	private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

	private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

	public static char[] encodeHex(byte[] data) {
		return encodeHex(data, true);
	}

	public static char[] encodeHex(byte[] data, boolean toLowerCase) {
		return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
	}

	protected static char[] encodeHex(byte[] data, char[] toDigits) {
		if (data == null)
			return null;
		int l = data.length;
		char[] out = new char[l << 1];
		for (int i = 0, j = 0; i < l; i++) {
			out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
			out[j++] = toDigits[0x0F & data[i]];
		}
		return out;
	}


	public static String encodeHexStr(byte[] data) {
		return encodeHexStr(data, true);
	}

	public static String encodeHexStr(byte[] data, boolean toLowerCase) {
		return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
	}


	protected static String encodeHexStr(byte[] data, char[] toDigits) {
		return new String(encodeHex(data, toDigits));
	}

	public static String formatHexString(byte[] data) {
		return formatHexString(data, false);
	}

	public static String formatHexString(byte[] data, boolean addSpace) {
		if (data == null || data.length < 1)
			return null;
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < data.length; i++) {
			String hex = Integer.toHexString(data[i] & 0xFF);
			if (hex.length() == 1) {
				hex = '0' + hex;
			}
			sb.append(hex);
			if (addSpace)
				sb.append(" ");
		}
		return sb.toString().trim();
	}

	public static byte[] decodeHex(char[] data) {

		int len = data.length;

		if ((len & 0x01) != 0) {
			throw new RuntimeException("Odd number of characters.");
		}

		byte[] out = new byte[len >> 1];

		// two characters form the hex value.
		for (int i = 0, j = 0; j < len; i++) {
			int f = toDigit(data[j], j) << 4;
			j++;
			f = f | toDigit(data[j], j);
			j++;
			out[i] = (byte) (f & 0xFF);
		}

		return out;
	}


	protected static int toDigit(char ch, int index) {
		int digit = Character.digit(ch, 16);
		if (digit == -1) {
			throw new RuntimeException("Illegal hexadecimal character " + ch
					+ " at index " + index);
		}
		return digit;
	}

	public static String chineseWordToGbk(String content) throws UnsupportedEncodingException {
		byte[] bytes = content.getBytes("GB2312");
		char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
				'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
		char[] buf = new char[bytes.length * 2];
		int a = 0;
		int index = 0;
		for (byte b : bytes) { // 使用除与取余进行转换
			if (b < 0) {
				a = 256 + b;
			} else {
				a = b;
			}
			buf[index++] = HEX_CHAR[a / 16];
			buf[index++] = HEX_CHAR[a % 16];
		}
		return new String(buf);
	}


	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.trim();
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	public static String  strToHex(String hexString) {
		String str = "";
		for (int i = 0; i < hexString.length(); i++) {
			int ch = (int) hexString.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str+"0D0A";
	}

	public static String  strToHexNoSpace(String hexString) {
		String str = "";
		for (int i = 0; i < hexString.length(); i++) {
			int ch = (int) hexString.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

	public static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	public static String extractData(byte[] data, int position) {
		return com.clj.fastble.utils.HexUtil.formatHexString(new byte[]{data[position]});
	}

	public static String bytesToAscii(byte[] bytes, int offset, int dateLen) {
		if ((bytes == null) || (bytes.length == 0) || (offset < 0) || (dateLen <= 0)) {
			return null;
		}
		if ((offset >= bytes.length) || (bytes.length - offset < dateLen)) {
			return null;
		}

		String asciiStr = null;
		byte[] data = new byte[dateLen];
		System.arraycopy(bytes, offset, data, 0, dateLen);
		try {
			asciiStr = new String(data, "GB2312");      //编码协议
//            asciiStr = new String(data, "ISO8859-1");
		} catch (UnsupportedEncodingException e) {
		}
		return asciiStr;
	}

	public static String bytesToAscii(byte[] bytes, int dateLen) {
		return bytesToAscii(bytes, 0, dateLen);
	}

	public static String bytesToAscii(byte[] bytes) {
		return bytesToAscii(bytes, 0, bytes.length);
	}

	/**
	 * 16进制字符串转为16进制字节流数据:以每两个字符分割转换为16进制形式,例如:"7E7E01" -> byte[]{0x7E,0x7E,0x01}
	 *
	 * @param hexString
	 * @return 字节数组
	 */
	public static byte[] HexString2Bytes(String hexString) {
		if (null == hexString || 0 == hexString.length()) {//hexString不存在
			return null;
		}
		byte[] ret = new byte[hexString.length() / 2];//2个字符为1个byte
		byte[] tmp = hexString.getBytes();//获取hexString字节数组
		for (int i = 0; i < (tmp.length / 2); i++) {//循环
			ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);//往字节数组中存放字节数据
		}
		return ret;
	}

	/**
	 * 将两个ASCII字符合成一个字节,例如:"7E" -> 0x7E
	 *
	 * @param highIndex 字节高位
	 * @param lowIndex  字节低位
	 * @return 字节数据
	 */
	public static byte uniteBytes(byte highIndex, byte lowIndex) {
		String highIndexStr = new String(new byte[]{highIndex});
		String lowIndexStr = new String(new byte[]{lowIndex});
		highIndex = Byte.decode("0x" + highIndexStr).byteValue();
		highIndex = (byte) (highIndex << 4);//左移4位去除高位的0
		lowIndex = Byte.decode("0x" + lowIndexStr).byteValue();
		return (byte) (highIndex ^ lowIndex);//将高4位和低4位异或运算成为一个byte
	}



	/**
	 * byte[]数组转换为16进制的字符串
	 *
	 * @param bytes 要转换的字节数组
	 * @return 转换后的结果
	 */
	public static String bytesToHexString(byte bytes) {
		StringBuilder sb = new StringBuilder();
		String hex = Integer.toHexString(0xFF & bytes);
		if (hex.length() == 1) {
			sb.append('0');
		}
		sb.append(hex);
		return sb.toString();
	}


	/**
	 * byte[]数组转换为16进制的字符串
	 *
	 * @param bytes 要转换的字节数组
	 * @return 转换后的结果
	 */
	public static String bytesToHexString(byte[] bytes) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String hex = Integer.toHexString(0xFF & bytes[i]);
			if (hex.length() == 1) {
				sb.append('0');
			}
			sb.append(hex);
		}
		return sb.toString();
	}

	/**
	 * 16进制转换成为string类型字符串
	 *
	 * @param s
	 * @return
	 */
	public static String hexStringToString(String s) {
		if (s == null || s.equals("")) {
			return null;
		}
		s = s.replace(" ", "");
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		try {
			s = new String(baKeyword, "GB2312");
			new String();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}


	/**
	 *  普通字符转换成16进制字符串
	 * @param str
	 * @return
	 */

	public static String decimalDigitsToHex(String str) {
		if(TextUtils.isEmpty(str)){
			return "";
		}

		String hex =Integer.toHexString(Integer.valueOf(str));
		if(hex.length()==1){
			hex="0"+hex;
		}

		return hex ;
	}


	/**
	 *  普通字符转换成16进制字符串
	 * @param str
	 * @return
	 */

	public static int hexToDecimal(String str) {
		if(TextUtils.isEmpty(str)){
			return 40;
		}
		return new BigInteger(str,16).intValue();
	}

	public static String hexToDecimalString(String str) {
		if(TextUtils.isEmpty(str)){
			return "11110000";
		}
		return new BigInteger(str,16).toString();
	}



}
